5.2.1 概述
SVG 全称是 Scalable Vector Graphics(可缩放矢量图形),即 SVG 是矢量图。与矢量图对应的是位图,Bitmap 就是位图,它由一个个像素点组成,当图片放大到一定大小时,就会出现马赛克现象,Photoshop 就是常用的位图处理软件。而矢量图则由一个个点组成,经过数学计算利用直线和曲线绘制而成,无论如何放大,都不会出现马赛克现象,Illustrator 就是常用的矢量图绘图软件。
SVG 与 Bitmap 相比有以下好处:
- SVG 使用 XML 格式定义图形,可被非常多的工具读取和修改。
- SVG 由点来存储,由计算机根据点信息绘图,不会失真,无须根据分辨率适配多套图标。
- SVG 的占用空间明显比 Bitmap 小。如 500px X 500px 的图像,转成 SVG 后占用的空间大小是 20KB,而 PNG 图片则需要 732KB 的空间。
- SVG 可以转换为 Path 路径,与 Path 动画相结合,可以形成丰富的动画。
对于 Android 5.0 以下的机型,可以通过引入 com.android.support:appcompat-v7:23.4.0 及以上版本进行支持。
Android 并没有对原生的 SVG 图像语法进行支持,而是以一种简化的方式对 SVG 进行兼容,也就是通过使用它的 path 标签,几乎可以实现 SVG 中的其他所有标签。这些东西可以通过工具来完成。
5.2.2 vector 标签与图像显示
res/drawable/svg.xml
效果图:
- vector 标签:指定画布大小,上图蓝框区域。
- path 标签:绘制路径,对应上图中的红色线段。
- width & height 属性:表示该 SVG 图形的具体大小。
- viewportWidth & viewportHeight 属性:表示 SVG 图形划分的比例。
width & height 类似于指定画布的大小,而 viewportWidth & viewportHeight 则是指将画布的宽、高分为多少个点,而 Path 中的点坐标都是以 viewportWidth & viewportHeight 的点数为坐标的,而不是 dp 值。此处将宽度 200dp 分为 100 个点,在高度 100dp 分为 50 个点,每个点有 2dp。而 path 中字母 M 表示 moveTo,字母 L 表示 lineTo,所以,这里代表从(50, 23) 到点 (100, 23) 画了一条线段。
1. path 标签
1)常用属性
- android:name:声明一个标记,类似于 ID。
- android:pathData:对 SVG 矢量图的描述。
- android:strokeWidth:画笔的宽度
- android:fillColor:填充颜色。
- android:fillAlpha:填充颜色的透明度。
- android:strokeColor:描边颜色。
- android:strokeWidth:描边宽度。
- android:strokeAlpha:描边透明度。
- android:strokeLineJoin:用于指定折线拐角形状,取值有 miter(结合处为锐角)、round(结合处为圆弧)、bevel(结合处为直线)。
- android:strokeLineCap:画出线条的终点的形状(线帽),取值有 butt(无线帽)、round(圆形线帽)、square(方形线帽)
- android:strokeMiterLimit:设置斜角的上限。当 strokeLineJoin 为 “round” 或 “bevel” 时,该属性无效。
2)android:trimPathStart 属性
该属性用于指定路径从哪里开始,取值为 0~1,表示路径开始位置的百分比。取值为 0 时,表示从头开始;取值为 1 时,整条路径不可见。
灰色部分代表的是被删除的部分,实际上是不会显示出来的,这里只是为了展示效果,下同。
3)android:trimPathEnd 属性
该属性用于指定路径的结束位置,取值为 0~1,表是路径结束位置的百分比。取值为 1 时,路径正常结束;取值为 0 时,表示从开始位置就已经结束了,即整条路径不可见。
4)android:trimPathOffset 属性
该属性用于指定路径的位移距离,取值 0~1。取值为 0 时,不位移;当取值 为 1 时,位移整条路径的长度。
5)android:pathData 属性
指定 SVG 图像的显示内容。
- M = moveTo(M X,Y):将画笔移动到指定的坐标位置。
- L = lineTo(L X,Y):画直线到指定的坐标位置。
- H = horizontal lineTo(H X):画水平线到指定的 X 坐标位置。
- V = vertical lineTo(V Y):画垂直线到指定的 Y 坐标位置。
- C = curveTo(C X1,Y1,X2,Y2,ENDX,ENDY):三阶贝济埃曲线。
- S = smooth curveTo(S X2,Y2,ENDX,ENDY):三阶贝济埃曲线。S 指令会将上一条指令的终点作为这条指令的起始点。
- Q = quadratic Bezier curve(Q X,Y,ENDX,ENDY):二阶贝济埃曲线。
- T = smooth quadratic Bezier curveTo(T ENDX,ENDY):映射前面路径后的终点。
- A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧线。
- Z = closePath():关闭路径。
使用上面的指令时,需要注意的几点:
- 坐标轴以(0,0)位中心,X轴水平向右,Y轴水平向下。
- 所有指令大小写均可,大写绝对定位,参照全局坐标系,小写相对定位,参照父容器坐标系。
- 指令和数据间的空格可以无视。
- 同一指令出现多次可以用一个。
2. group 标签
group 标签用于定义一系列路径或者将 path 标签分组。具有以下常用属性。
- android:name:组的名称,用于与动画相关联。
- android:rotation:指定该组图像的旋转度数。
- android:pivotX:定义缩放和旋转该组时的 X 参考点。
- android:pivotY:定义缩放和旋转该组时的 Y 参考点。
- android:scaleX:指定该组 X 轴缩放大小。
- android:scaleY:指定该组 Y 轴缩放大小。
- android:translateX:指定该组沿 X 轴平移的距离。
- android:translateY:指定该组沿 Y 轴平移的距离。
示例:围绕画布中心旋转 90 度。
3. 制作 SVG 图像
方法一:设计软件
如果有绘图基础,可以直接使用 Illustrator 或在线 SVG 工具制作 SVG 图像(如 http://editor.method.ac/),或者通过 SVG 源文件下载网站下载后进行编辑。
方法二:Iconfont
有很多 Iconfont 开源网站,比如国内的阿里巴巴矢量图库,地址为 http://www.iconfont.cn/。
4. 在 Android 中引入 SVG 图像
在 Android 中是不支持 SVG 图像解析的,我们必须将 SVG 图像转换为 vector 标签描述,这里同样有两种方法。
方法一:在线转换。
This tool has been deprecated. Use official Vector Asset Studio instead.
方法二:Vector Asset Studio
Android Studio 2.0 及以上版本中支持创建 Vector 文件,如下图所示。
5. 示例
1)引入兼容包
在项目的 build.gradle 脚本中添加对 Vector 兼容性的支持。
2)生成 Vector 图像
使用前面例子中的一条横线的 Vector 图像(src/drawable/svg.xml)
3)在 ImageView、ImageButton 中使用
在代码中设置
本人测试使用 android:background=”@drawable/svg” 也是正常的。测试机型 Pixel XL,Android 7.1.2。
4)在 Button、RadioButton 中使用
Button 并不能直接通过 app:srcCompat 属性来使用 Vector 图像,而需要通过 selector 标签来使用(selector_svg.xml)
如果到这里并不能直接运行,需要把下面这段代码放在 Activity 的前面。
本人测试可以直接使用 android:background=”@drawable/svg” 并且不需要在 Activity 中加入上述代码 即可正常运行。测试机型 Pixel XL,Android 7.1.2。
5.2.3 动态 Vector
实现 Vector 动画,步骤如下:
1)使用上述 drawable/svg.xml
2)创建 animator/anim_trim_start.xml 文件
3)关联 Vector & Animator。drawable/animated_vector.xml
4)最后在代码中使用
效果图如下所示:
5.2.4 示例:输入搜索动画
1. 准备 SVG 图像
res/drawable/svg.xml
2. 准备动画
res/animator/anim_bar_trim_start.xml
res/animator/anim_search_trim_start.xml
关联 Vector & Animator
3. 布局与开始动画
res/layout/act_main.xml
开始动画代码: